import logging
from typing import List

logger = logging.getLogger(__name__)

try:
    from volcengine.dns.v20180801.dns_service import DnsService
except ImportError:
    DnsService = None
    logger.warning("Volcengine SDK not found or structure mismatch. VolcanoProvider will not work.")

from app.schemas.dns import (
    DNSRecord,
    DNSRecordCreate,
    DNSRecordIdentifier,
    DNSRecordStatus,
    DNSRecordType,
    DNSRecordUpdate,
    DomainSummary,
)
from app.services.cloud_providers.base import BaseProvider


class VolcanoProvider(BaseProvider):
    """火山引擎 (Volcengine) DNS 适配器。"""

    def __init__(self, access_key: str, secret_key: str, region: str = "cn-north-1") -> None:
        super().__init__(access_key, secret_key, region)
        if DnsService is None:
            raise ImportError("Volcengine SDK not properly installed.")
        self.client = DnsService()
        self.client.set_ak(access_key)
        self.client.set_sk(secret_key)
        # Volcano SDK might not need region for global DNS, but we set it if needed.

    def list_domains(self) -> List[DomainSummary]:
        try:
            # Volcano ListDomains
            resp = self.client.list_domains({})
            results = []
            if "Result" in resp and "Domains" in resp["Result"]:
                for item in resp["Result"]["Domains"]:
                    results.append(
                        DomainSummary(
                            domain=item["DomainName"],
                            provider="volcano",
                            record_count=item.get("RecordCount", 0),
                        )
                    )
            return results
        except Exception as err:
            logger.error(f"Volcano list_domains failed: {err}")
            raise

    def list_records(self, domain: str) -> List[DNSRecord]:
        try:
            body = {"DomainName": domain}
            resp = self.client.list_records(body)
            results = []
            if "Result" in resp and "Records" in resp["Result"]:
                for item in resp["Result"]["Records"]:
                    results.append(
                        DNSRecord(
                            id=str(item["RecordID"]),
                            provider="volcano",
                            domain=domain,
                            record_type=DNSRecordType(item["Type"].upper()),
                            name=item["Host"],
                            value=item["Value"],
                            ttl=item.get("TTL", 600),
                            status=DNSRecordStatus.active if item["Enable"] else DNSRecordStatus.paused,
                        )
                    )
            return results
        except Exception as err:
            logger.error(f"Volcano list_records failed: {err}")
            raise

    def create_record(self, payload: DNSRecordCreate) -> DNSRecord:
        try:
            body = {
                "DomainName": payload.domain,
                "Host": payload.name,
                "Type": payload.record_type.value,
                "Value": payload.value,
                "TTL": payload.ttl,
                "Line": "default",  # 默认线路
            }
            resp = self.client.create_record(body)
            # Volcano returns RecordID
            record_id = resp["Result"]["RecordID"]
            
            # If status is paused, we might need a separate call or check if create supports it.
            # Volcano CreateRecord doesn't seem to have 'Enable' param in some versions, assume active.
            if payload.status == DNSRecordStatus.paused:
                self.client.update_record_status({"RecordID": record_id, "Enable": False})

            return DNSRecord(
                id=str(record_id),
                provider="volcano",
                domain=payload.domain,
                record_type=payload.record_type,
                name=payload.name,
                value=payload.value,
                ttl=payload.ttl,
                status=payload.status,
            )
        except Exception as err:
            logger.error(f"Volcano create_record failed: {err}")
            raise

    def update_record(self, domain: str, payload: DNSRecordUpdate) -> DNSRecord:
        try:
            # We need to fetch original record if fields are missing, similar to Tencent
            current_records = self.list_records(domain)
            current = next((r for r in current_records if r.id == payload.id), None)
            if not current:
                raise KeyError("Record not found")

            body = {
                "RecordID": payload.id,
                "Host": payload.name if payload.name else current.name,
                "Type": payload.record_type.value if payload.record_type else current.record_type.value,
                "Value": payload.value if payload.value else current.value,
                "TTL": payload.ttl if payload.ttl else current.ttl,
                "Line": "default",
            }
            
            self.client.update_record(body)

            if payload.status is not None:
                enable = payload.status == DNSRecordStatus.active
                if (current.status == DNSRecordStatus.active) != enable:
                    self.client.update_record_status({"RecordID": payload.id, "Enable": enable})

            return DNSRecord(
                id=payload.id,
                provider="volcano",
                domain=domain,
                record_type=DNSRecordType(body["Type"]),
                name=body["Host"],
                value=body["Value"],
                ttl=body["TTL"],
                status=payload.status if payload.status else current.status,
            )
        except Exception as err:
            logger.error(f"Volcano update_record failed: {err}")
            raise

    def delete_record(self, domain: str, payload: DNSRecordIdentifier) -> None:
        try:
            body = {"RecordID": payload.id}
            self.client.delete_record(body)
        except Exception as err:
            logger.error(f"Volcano delete_record failed: {err}")
            raise

    def batch_delete_records(self, domain: str, record_ids: List[str]) -> int:
        # Volcano might not have batch delete, so we loop.
        count = 0
        for rid in record_ids:
            try:
                self.delete_record(domain, DNSRecordIdentifier(id=rid))
                count += 1
            except Exception:
                pass
        return count
